#include "LoginWindow.h"
#include "ui_LoginWindow.h"
#include "globalTable.hpp"
#include <QMessageBox>
#include <QSettings>

#include "src/nlohmannjson.hpp"

LoginWindow::LoginWindow(xdgTcpClient *client, QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::LoginWindow)
    , m_client(client)
{
    ui->setupUi(this);
    this->resize (400,180);

    // --- 1. 界面设置 ---
    this->setWindowIcon (QIcon(":/img/camera.png")); // 设置窗口图标
    this->setWindowTitle ("欢迎登录      ---      服务器连接失败！！！");
    this->setFont (g_font);
    ui->widget_register->hide (); // 隐藏注册界面

    ui->pushButton_login->setCursor(Qt::PointingHandCursor); // 手型指针
    ui->pushButton_register->setCursor (Qt::PointingHandCursor);
    ui->pushButton_goregister->setCursor (Qt::PointingHandCursor);
    ui->pushButton_gologin->setCursor (Qt::PointingHandCursor);

    QSettings settings("config.ini", QSettings::IniFormat);
    settings.beginGroup("data");
    if( settings.value ("remember").toBool () ){
        ui->checkBox_remember->setChecked (true);
        ui->lineEdit_user->setText ( settings.value ("account").toString () );
        ui->lineEdit_pwd->setText ( settings.value ("pwd").toString () );
    } // 这个不会触发编辑框失去焦点的事件，因打开鼠标就在登录编辑框里，故点登录按钮的时候才会触发
    settings.endGroup();

    // --- 2. 连接 UI 信号 ---
    connect(ui->pushButton_login, &QPushButton::clicked, this, &LoginWindow::onLoginClicked);
    connect(ui->pushButton_register, &QPushButton::clicked, this, &LoginWindow::onRegisterClicked);
    connect(ui->pushButton_goregister, &QPushButton::clicked, this, &LoginWindow::onGoRegisterClicked);
    connect(ui->pushButton_gologin, &QPushButton::clicked, this, &LoginWindow::onGoLoginClicked);

    connect(ui->lineEdit_user, &QLineEdit::editingFinished, this, &LoginWindow::onUserEditingFinished);
    connect(ui->lineEdit_user_2, &QLineEdit::editingFinished, this, &LoginWindow::onUser2EditingFinished);


    // --- 3. 连接网络信号，采用 "先连接，再检查" 模式 ---
    connect(m_client, &xdgTcpClient::connected,
            this, &LoginWindow::onClientConnected);
    connect(m_client, &xdgTcpClient::disconnected,
            this, &LoginWindow::onClientDisconnected);
    connect(m_client, &xdgTcpClient::messageReceived,
            this, &LoginWindow::onMessageReceived);

    // --- 4. 检查 + 发起连接 ---
    if (m_client->isConnected()) {
        // (如果 main 中已经连接)
        onClientConnected();
    } else {
        // (在 main 中没有连接) 我们发起连接
        //m_client->connectToServer("sc.myzrd.cn", 27059); // <-- 在这里发起连接
        m_client->connectToServer("192.168.233.135", 8080); // <-- 在这里发起连接
    }

}



LoginWindow::~LoginWindow()
{
    delete ui;
}


// tcp连接西信号
void LoginWindow::onClientConnected()
{
    this->setWindowTitle ("欢迎登录      ---      服务器连接成功");
}

// tcp断开连接信号
void LoginWindow::onClientDisconnected()
{
    this->setWindowTitle ("欢迎登录      ---      服务器断开连接");
}

// tcp数据到达信号
void LoginWindow::onMessageReceived(const QByteArray& message)
{
    // QString jsonStr(message.constData() + 4, message.size() - 4);
    QString jsonStr(message.mid(4));
    nlohmann::json j;
    int type;
    bool success;
    QString salt;

    try {
        j = nlohmann::json::parse(jsonStr.toStdString()); // 解析 JSON，如果解析成功，直接返回
        type = j["type"];

    } catch (const nlohmann::json::parse_error& e) {
        QString str = "服务器数据解析失败：";
        str += e.what();
        QMessageBox::warning(this, "温馨提示：", str);
        return;

    } catch (const std::exception& e) {
        QString str = "异常：";
        str += e.what();
        QMessageBox::warning(this, "温馨提示：", str);
        return;

    }


    // 解析成功，类型判断
    if(type == 101){
        try {
            success = j["success"];
            salt = QString::fromStdString(j["salt"].get<std::string>());
        } catch (const nlohmann::json::type_error& e) {
            QString str = "服务器数据解析失败，JSON 类型错误：";
            str += e.what();
            QMessageBox::warning(this, "温馨提示：", str);

        } catch (const nlohmann::json::out_of_range& e) {
            QString str = "服务器数据解析失败，JSON 键不存在：";
            str += e.what();
            QMessageBox::warning(this, "温馨提示：", str);

        } catch (const std::exception& e) {
            QString str = "其他错误：";
            str += e.what();
            QMessageBox::warning(this, "温馨提示：", str);
        }

        if ( !ui->widget_register->isHidden () ) {
            if(success){
                ui->label_description->setText ("此用户已经被注册了.");
            }else{
                ui->label_description->setText ("此用户可以被注册.");
            }
        }
        g_salt = salt; // 记录盐值


    }else if(type == 102){
        QString tip;

        try {
            success = j["success"];
            tip = QString::fromStdString(j["tip"].get<std::string>());
        } catch (const nlohmann::json::type_error& e) {
            QString str = "服务器数据解析失败，JSON 类型错误：";
            str += e.what();
            QMessageBox::warning(this, "温馨提示：", str);

        } catch (const nlohmann::json::out_of_range& e) {
            QString str = "服务器数据解析失败，JSON 键不存在：";
            str += e.what();
            QMessageBox::warning(this, "温馨提示：", str);

        } catch (const std::exception& e) {
            QString str = "其他错误：";
            str += e.what();
            QMessageBox::warning(this, "温馨提示：", str);
        }

        if(success){
            QMessageBox::information (this, "温馨提示：", "恭喜你注册成功：" + ui->lineEdit_user_2->text ());
        }else{
            QMessageBox::warning (this, "温馨提示：", "注册失败：" + tip);
        }

    }else if(type == 103){
        try {
            success = j["success"];
        } catch (const nlohmann::json::type_error& e) {
            QString str = "服务器数据解析失败，JSON 类型错误：";
            str += e.what();
            QMessageBox::warning(this, "温馨提示：", str);

        } catch (const nlohmann::json::out_of_range& e) {
            QString str = "服务器数据解析失败，JSON 键不存在：";
            str += e.what();
            QMessageBox::warning(this, "温馨提示：", str);

        } catch (const std::exception& e) {
            QString str = "其他错误：";
            str += e.what();
            QMessageBox::warning(this, "温馨提示：", str);
        }

        if(success){
            QMessageBox::information (this, "温馨提示：", "登录成功，欢迎你：" + ui->lineEdit_user->text ());
            g_account = ui->lineEdit_user->text ();
            g_pwd = g_calculateMad5 (ui->lineEdit_pwd->text ());

            if( ui->checkBox_remember->isChecked () ){
                QSettings settings("config.ini", QSettings::IniFormat);
                settings.beginGroup("data");
                settings.setValue("remember", true);
                settings.setValue("account", g_account);
                settings.setValue ("pwd", ui->lineEdit_pwd->text ());
                settings.endGroup();
            }else{
                QSettings settings("config.ini", QSettings::IniFormat);
                settings.beginGroup("data");
                settings.setValue("remember", false);
                settings.setValue("account", "");
                settings.setValue ("pwd", "");
                settings.endGroup();
            }

            // ****** 关键的交接逻辑 ******

            // 1. 创建主窗口 (并注入 client)
            //    (MainWindow的构造函数会自动 connect 信号)
            m_mainWindow = new MainWindow(m_client);
            m_mainWindow->setAttribute(Qt::WA_DeleteOnClose); // 设置窗口属性，字面意思就是“关闭时删除”

            // 2. 显示主窗口
            m_mainWindow->show();

            // 3. (关键) 断开 本窗口 的所有信号槽
            disconnect(m_client, nullptr, this, nullptr);

            // 4. 关闭登录窗口
            this->close(); // close() 会在稍后安全地 delete this

        }else{
            QMessageBox::warning (this, "温馨提示：", "登录验证失败，请检查用户名或密码！");
        }



    }




}

// 登录按钮
void LoginWindow::onLoginClicked() {

    nlohmann::json j;

    j["type"] = 103;
    j["data"]["account"] = ui->lineEdit_user->text ().toStdString ();
    j["data"]["password"] = g_calculateMad5 (ui->lineEdit_pwd->text ()).toStdString ();
    QString jsonStr = QString::fromStdString (j.dump (0));

    m_client->sendMessage ( jsonStr.toUtf8 () );

}

// 注册按钮
void LoginWindow::onRegisterClicked() {
    nlohmann::json j;

    j["type"] = 102;
    j["data"]["account"] = ui->lineEdit_user_2->text ().toStdString ();
    j["data"]["password"] = g_calculateMad5 (ui->lineEdit_pwd_2->text ()).toStdString ();
    QString jsonStr = QString::fromStdString (j.dump (0));

    m_client->sendMessage ( jsonStr.toUtf8 () );

}

// 去注册页面
void LoginWindow::onGoRegisterClicked() {
    ui->widget_login->hide (); // 隐藏登录界面
    ui->widget_register->show ();
}

// 去登录页面
void LoginWindow::onGoLoginClicked() {
    ui->widget_register->hide (); // 隐藏注册界面
    ui->widget_login->show ();
}

// 登录用户名编辑框
void LoginWindow::onUserEditingFinished() {
    QString text = ui->lineEdit_user->text();
    if( text.isEmpty ()) { return ; }

    nlohmann::json json;
    json["type"] = 101;
    json["data"]["account"] = text.toStdString ();

    QString jsonStr = QString::fromStdString (json.dump (0));
    m_client->sendMessage (jsonStr.toUtf8 ());
}

// 注册用户名编辑框
void LoginWindow::onUser2EditingFinished() {
    QString text = ui->lineEdit_user_2->text();
    if( text.isEmpty ()) { return ; }

    nlohmann::json json;
    json["type"] = 101;
    json["data"]["account"] = text.toStdString ();

    QString jsonStr = QString::fromStdString (json.dump (0));
    m_client->sendMessage (jsonStr.toUtf8 ());
}


